import struct
import binascii
import multiprocessing
import sys
import logging
import time
import traceback
from multiprocessing import Process, Queue
import subprocess 
import os
import json
import asyncio
import http.client
import urllib
import socket
import time
import select
import datetime
from time import ctime
import threading
import bendi 

pipeibiao = [{"充":0,"state":"0"},{"快充":1,"state":"0"},{"普充":2,"state":"0"},{"空调":3,"state":"0"},{"电视":4,"state":"0"},{"冰箱":5,"state":"0"},{"浴霸":6,"state":"0"},{"电烙铁":7,"state":"0"},{"灯":8,"state":"0"},{"电水壶":9,"state":"0"},{"电脑":10,"state":"0"}]
CWD_DIR = os.path.split(os.path.abspath(__file__) )[0]
fanip = {}
adress1 = "120.24.60.81"
#adress1 = "192.168.1.102"
port1 = 8800
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((adress1,port1))
print("lian jie success")

address = "0.0.0.0"
port = 1000
Sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
Sock.bind((address,port))
epoll = select.epoll()
fd = Sock.fileno()
epoll.register(fd,select.EPOLLIN)
Sock_dict = {}
Sock_dict[fd] = Sock
Sock.listen(5)
print("listen success")


def list_to_json(listData):
	list_json = []
	#for elem in listData:
	list_json.append(listData)
	dataJson = json.dumps(list_json,ensure_ascii=False)
	return dataJson
def xintiao_to_json(listData):
	list_json = []
	#for elem in listData:
	list_json.append((listData))
	dataJson = json.dumps(list_json,ensure_ascii=False)
	return dataJson
def httpSend(host, url, port, data_str):
	conn = http.client.HTTPConnection(host, port, timeout = 5)
	data = {'data':data_str}
	headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "*/*"}
	params = urllib.parse.urlencode(data)
	conn.request("POST", url, params, headers)
	response = conn.getresponse()
	data = response.read()
	conn.close()
	return data
def httpSend1(host, url, port, data_str):
	conn = http.client.HTTPConnection(host, port, timeout = 5)
	data = {'env':data_str}
	headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "*/*"}
	params = urllib.parse.urlencode(data)
	conn.request("POST", url, params, headers)
	response = conn.getresponse()
	data = response.read()
	conn.close()
	return data
def httpSend2(host, url, port, data_str):
	conn = http.client.HTTPConnection(host, port, timeout = 5)
	data = {'arcdata':data_str}
	headers = {"Content-type": "application/x-www-form-urlencoded","Accept": "*/*"}
	params = urllib.parse.urlencode(data)
	conn.request("POST", url, params, headers)
	response = conn.getresponse()
	data = response.read()
	conn.close()
	return data
def client(p):
	epoll = select.epoll()
	#获取创建好的sock的文件描述符
	fd = sock.fileno()
	epoll.register(fd,select.EPOLLIN)
	while True:
		try:
			events = epoll.poll(1)
			for fileno,event in events:
				if fileno == fd:
					if event & select.EPOLLIN:
						datas = sock.recv(128)
						if len(datas)>0:
							print("收到阿里云反向控制信息",datas.decode())
							zhiling = datas.decode()
							p.put(zhiling)
		except:
			print("接收阿里云信号服务正在重新启动")
										
def client1(q):#发送数据给阿里云
	while True:
		try:
			data=q.get()
			#bendi.data_write(data)#仅此一处加入存入本地
			if len(data)>0 and data is not None:
				try:
					sock.send(('%s' % (data)).encode())
					print("数据已发送给了阿里云",data)
				except Exception as e:
					print("数据发送失败 正在重新连接",e)
		except:
			print("上发阿里云数据正在重新启动")
			
def server1(p):
	while True:
		try:
			re = p.get()
			print(re)
			if len(re) > 0:
				if (re.split(';')[-1]).split('=')[-1]=='off':
					print("************************************************************************")
					print("************************************************************************")
					print("正在关闭继电器 %s号基站下%s号房间"%((re.split(';')[0]).split('=')[-1],(re.split(';')[1]).split('=')[-1]))
					print("************************************************************************")
					print("************************************************************************")
					se ="AB0"
					Sock_dict[fanip[int((re.split(';')[1]).split('=')[-1])]].send(('%s' % (se)).encode())
				if (re.split(';')[-1]).split('=')[-1]=='on':
					print("************************************************************************")
					print("************************************************************************")
					print("正在打开继电器 %s号基站下%s号房间"%((re.split(';')[0]).split('=')[-1],(re.split(';')[1]).split('=')[-1]))
					print("************************************************************************")
					print("************************************************************************")
					se ="AB1"
					Sock_dict[fanip[int((re.split(';')[1]).split('=')[-1])]].send(('%s' % (se)).encode())
				if (re.split(';')[-1]).split('=')[-1]=='baojing_kai':
					print("************************************************************************")
					print("************************************************************************")
					print("正在打开报警功能 %s号基站下%s号房间"%((re.split(';')[0]).split('=')[-1],(re.split(';')[1]).split('=')[-1]))
					print("************************************************************************")
					print("************************************************************************")
					se ="AC1"
					Sock_dict[fanip[int((re.split(';')[1]).split('=')[-1])]].send(('%s' % (se)).encode())
				if (re.split(';')[-1]).split('=')[-1]=='baojing_guan':
					print("************************************************************************")
					print("************************************************************************")
					print("正在关闭报警功能 %s号基站下%s号房间"%((re.split(';')[0]).split('=')[-1],(re.split(';')[1]).split('=')[-1]))
					print("************************************************************************")
					print("************************************************************************")
					se ="AC0"
					Sock_dict[fanip[int((re.split(';')[1]).split('=')[-1])]].send(('%s' % (se)).encode())

		except:
			print("下发魔眼服务正在重新启动")
def client_echo(client,Sock_dict,fileno,q,epoll,data):
	if len(data) != 0 and data is not None:
		print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
		if data is not None and data[0] == 170 and data[1]==187:
			#print(data)
			try:
				data = struct.  unpack('B'*76, data)
			except Exception as e:
				print(e)
			#fanip[int(256*data[3]+data[4])]=fileno
			print("检测到电器数据")
			try:
				cmd = ('sudo ./recognize '+ '%d '*68) %(data[6:-2])
				p = subprocess.Popen(cmd , shell=True , stdout=subprocess.PIPE , cwd=CWD_DIR)
				send =[]
				name = p.stdout.read()
				name=name.decode('utf-8')
				print(name)
				if len(name)>0:
					#print("检测到数据",name)
					for elem in name.split(','):
						send.append(elem)
					dianqi={}
					dianqi["station_id"] = str(data[3])
					dianqi["room_id"] = str(data[4])
					dianqi['totalpower'] = str(send[0])
					dianqi["power"] = str(send[1])
					dianqi["name"] = str(send[2])
					dianqi["state"] = str(send[3])
					dataJson = list_to_json(dianqi)
					print("数据正在匹配",dataJson)
					for elem in json.loads(dataJson) :
						for xx in pipeibiao:
							if elem["name"] in xx:
								st = xx["state"]

								if elem["state"]=="0" and st=="0" :
									xx["state"] = "0"
									print("匹配到波动数据")

								elif elem["state"]=="1":
									xx["state"]="1"
									#q.put(dataJson)
									print(dataJson,type(dataJson))
									xx = httpSend("120.26.117.32","/remotestation/message",80,dataJson)
									#print(xx)
									#xx0 = httpSend("192.168.1.104","/remotestation/message",6060,dataJson)
									print("设备输入")

								elif elem["state"]=="0" and st=="1":
									xx["state"]="0"
									#q.put(dataJson)
									print(dataJson,type(dataJson))
									xx1 = httpSend("120.26.117.32","/remotestation/message",80,dataJson)
									#print(xx1)
									#xx11 = httpSend("122.168.1.104","/remotestation/message",6060,dataJson)
									print("设备关闭")
			except :
				print("没有匹配数据")
		if data is not None and data[0]==170 and data[1]==204:
			data = struct.  unpack('B'*12, data)
			print("心跳+环境数据",data)
			louhao = data[3]
			fangjianhao = data[4]
			pm25 = data[7]+256*data[8]
			zaosheng = data[9]
			wendu = data[5]
			shidu = data[6]
			#print("房间号:%d PM2.5:%d 噪声:%d 温度:%d 湿度:%d " % (fangjianhao,pm25,zaosheng,wendu,shidu))
			huanjing ={}
			huanjing["station_id"] = str(data[3])
			huanjing["room_id"]=str(data[4])
			fanip[int(data[4])]=fileno
			print("房间号",str(data[4]))
			huanjing["pm"]=str(pm25)
			huanjing["noise"]=str(zaosheng)
			huanjing["temp"]=str(wendu)
			huanjing["hum"]=str(shidu)
			xintiao_json=xintiao_to_json(huanjing)
			#print(xintiao_json)
			q.put(xintiao_json)
			print(xintiao_json,type(xintiao_json))
			xx2 = httpSend1("120.26.117.32","/remotestation/env",80,xintiao_json)
			#print(xx2)
			#xx22 = httpSend1("192.168.1.104","/remotestation/env",6060,xintiao_json)
			#print(xx22)
		if data is not None and data[0]==187 and data[1]==170 :
			data = struct.  unpack('B'*9, data)
			data = list(data)
			print("电弧数据")
			dianhu = {}
			dianhu["station_id"] = str(data[3])
			dianhu["room_id"] = str(data[4])
			dianhu["state"] = str(data[6])
			list_json = []
			list_json.append((dianhu))
			dataJsona = json.dumps(list_json,ensure_ascii=False)
			print(dataJsona,type(dataJsona))
			#fanip[int(data[4])]=fileno
			#q.put(dataJsona)
			xx3 = httpSend2("120.26.117.32","/remotestation/arc",80,dataJsona)
			#xx33 = httpSend2("192.168.1.104","/remotestation/arc",6060,dataJsona)
			#print(xx3)
			#print(xx3)

def server(q,p):
	connections = {}
	requests = {}
	responses = {}
	while True:
		try:
			try:
				events = epoll.poll(1)
			except Exception as e:
				print("lj",e)
			for fileno,event in events:
				if fileno == fd:
					(client,address) = Sock.accept()
					client.setblocking(0)
					epoll.register(client.fileno(),select.EPOLLIN)
					Sock_dict[client.fileno()] = client
				elif event & select.EPOLLIN:
					print("------recvdata---------")
					try:
						data = Sock_dict[fileno].recv(1024)
					except Exception as e:
						print("接收数据",e)
					if not data:
						Sock_dict[fileno].close()
						del Sock_dict[fileno]
						del data[Sock_dict[fileno]]
					#print(data)
					if len(data)>0:
						#print(data)
						epoll.modify(fileno, select.EPOLLOUT)
						t = threading.Thread(target=client_echo, args=(client,Sock_dict,fileno,q,epoll,data,))
						t.start()
						time.sleep(1)
						t._Thread__stop()
						t.join()
				elif event & select.EPOLLHUP:
					print("end hup---")
					epoll.unregister(fileno)
					Sock_dict[fileno].close()
					del Sock_dict[fileno]

		except Exception as e:
			print(e)
def main():
	try:
		q = Queue()#心跳
		p = Queue()#反向控制数据
		threads = []
		t1 = threading.Thread(target=server,args=(q,p,))
		threads.append(t1)
		t2 = threading.Thread(target=client,args=(p,))
		threads.append(t2)
		t3 = threading.Thread(target=client1,args=(q,))
		threads.append(t3)
		t4 = threading.Thread(target=server1,args=(p,))
		threads.append(t4)
		# t5 = threading.Thread(target=ping,args=(p,))
		# threads.append(t5)
		for t in threads:
			t.start()
	except Exception as e:
		print(e)

if __name__ == "__main__":
	main()


		



